<?PHP

/**
*	patRSS  - Resource description framework Site Summary helper class
*
*	@access		public
*	@version	0.2
*	@author		Sebastian Mordziol <argh@php-tools.net>, Stephan Schmidt <schst@php-tools.net>
*/
class patRSS
{
/**
*	store found elements
*	@var	array	$elements
*/
	var $elements	=	array();

/**
*	temporary data storeage
*	@var	string	$cdata
*/
	var $cdata;

/**
*	temporary element storeage
*	@var	string	$cdata
*/
	var $currentElement;
	
/*
*	Constructor - initiates the parsing process
*
*	@access	public
*	@param	string	$uri	path/url to the XML document that should be parsed.
*/
	function patRSS( $uri )
	{
		if( $fp = @fopen( $uri, "r" ) )
		{
			$parser = xml_parser_create();
			xml_set_object( $parser, $this );
			xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 1 );
			xml_set_character_data_handler( $parser, "cdataHandler" );
			xml_set_element_handler( $parser, "startElementHandler", "endElementHandler" );
		
			while( $xml = fread( $fp, 4096 ) ) 
			{
			    if( !xml_parse( $parser, $xml, feof( $fp ) ) ) 
					$error	=	"XML ERROR: ".xml_error_string( xml_get_error_code( $parser ) )." at line ".xml_get_current_line_number( $parser );
			}
			
			xml_parser_free($parser);
			
			fclose( $fp );
		}
	}

/**
*	start element handler
*	called by sax
*
*	@access	private
*	@param	object	$parser		parser resource
*	@param	string	$element	name of element
*	@param	array	$attribs	all attributes
*/	
	function startElementHandler( $parser, $element, $attribs )
	{
		// clear previous cdata contents if any.
		$this->cdata	=	"";
		switch( $element )
		{
			case "CHANNEL":
			case "IMAGE":
			case "ITEM":
			case "TEXTINPUT":
				$this->currentElement	=	array();
				break;
			
			default:
				break;
		}
	}

/**
*	CData element handler
*	called by sax
*
*	@access	private
*	@param	object	$parser		parser resource
*	@param	string	$data		cdata
*/	
	function cdataHandler( $parser, $data )
	{
		$this->cdata	.=	$data;
	}
	
/**
*	end element handler
*	called by sax
*
*	@access	private
*	@param	object	$parser		parser resource
*	@param	string	$element	name of element
*/	
	function endElementHandler( $parser, $element )
	{
		switch( $element )
		{
			case "CHANNEL":
			case "IMAGE":
			case "ITEM":
			case "TEXTINPUT":
				$this->currentElement["type"]	=	strtolower( $element );
				array_push( $this->elements, $this->currentElement );
				break;
			
			default:
				// save this tag in the current element, as it is a subelement.
				$this->currentElement[strtolower( $element )]	=	$this->cdata;
				break;
		}
	}
	
/**
*	get channel info
*
*	@access	public
*	@return	array	$info	channel information
*/	
	function getChannelInfo()
	{
		list( $result )	=	$this->stripType( $this->getElements( "channel" ) );
		return $result;
	}
	
/**
*	get images
*
*	@access	public
*	@return	array	$images	images
*/	
	function getImages( $limit = -1 )
	{
		return $this->stripType( $this->getElements( "image", $limit ) );
	}

/**
*	get all items / articles
*
*	@access	public
*	@return	array	$items	items
*/	
	function getItems( $limit = -1 )
	{
		return $this->stripType( $this->getElements( "item", $limit ) );
	}

/**
*	get inputs
*	used to start a search
*
*	@access	public
*	@return	array	$inputs	inputs
*/	
	function getTextinputs( $limit = -1 )
	{
		return $this->stripType( $this->getElements( "textinput", $limit ) );
	}

/*
*	Strips the type attribute from an element, used by the wrapper methods to
*	prepare the data for direct output.
*
*	@access	private
*	@param	array	$data	the array to strip of the type tags.
*/
	function stripType( $data )
	{
		for( $i=0; $i < count( $data ); $i++ )
			unset( $data[$i]["type"] );
			
		return $data;
	}
	
/*
*	Retrieves elements from the parsed rss file. Used by the wrapper methods to retrieve data.
*
*	@access	public
*	@param	string	$type	the type of the elements to retrive (channel|image|item|textinput).
*	@param	int		$limit	the maximum amount of elements to retrive. Default is -1, unlimited.
*/
	function getElements($type, $limit = -1)
	{
		$result	=	array();
	
		for( $i=0; $i < count($this->elements); $i++ )
		{
			if( $limit != -1 && $i > $limit+1 )
				break;

			if( $this->elements[$i]["type"] == $type )
				array_push( $result, $this->elements[$i] );
		}
		
		if( empty( $result ) )
			return false;
		
		return $result;
	}
}
?>